plant system


A Project By Zhihao Xu(zx334), Yisi Sun (ys2257).


Demonstration Video


Introduction

The proposed project aims to create an "Autonomous Plant Monitoring System" using a Raspberry Pi. This system would continuously monitor the health and needs of household plants and notify the user accordingly. The Raspberry Pi would be equipped with sensors to measure parameters like soil moisture, ambient light, and ambient temperature. The data from these sensors would be processed to determine if the plant needs watering, more sunlight, or if it's too hot/cold for it. Additionally, a camera module attached to the Pi could take periodic pictures of the plant, allowing users to visually track its growth and health over time.


Project Objective:

The goal of the project is to develop an "Autonomous Plant Monitoring System" that leverages a Raspberry Pi to monitor household plants' health and environmental needs. The system will utilize sensors to measure soil moisture, light, and temperature, and a camera to visually monitor plant growth. It will process this data to determine if the plant's environmental conditions need adjusting.


Design

Our project, centered around the Raspberry Pi 4, epitomizes this integration, aiming to revolutionize the way plant are monitored and managed. At the heart of our system is the Raspberry Pi 4, a powerful yet compact computing solution, which serves as the cornerstone of our smart system. Utilizing its robust processing capabilities, we have developed a comprehensive system that not only monitors the critical environmental parameters of the plant but also allows for remote management through a user-friendly web interface. Key to our system's monitoring capabilities are two primary components: a camera and a DHT11 temperature, humidity sensor and soil humidity sensor. The camera, strategically positioned within the system, streams real-time visual data, providing invaluable insights into the plant's health and growth patterns. Complementing this visual monitoring, the DHT11 sensor continually assesses the ambient temperature and humidity levels, ensuring that the plants are in an optimal growing environment. What sets our system apart is its interactive web interface. Designed with simplicity and functionality in mind, this interface not only displays the real-time data collected by the Raspberry Pi but also empowers users with control features. We have incorporated two critical control functions into the website: a watering feature and a supplemental lighting feature. With the click of a button, users can activate the watering system, ensuring the plants receive adequate hydration. Similarly, the supplemental lighting feature can be engaged to provide extra light, crucial for plant growth during periods of insufficient natural sunlight.

Generic placeholder image

structure diagram

Generic placeholder image

website

Generic placeholder image

overview


Testing

In our project's testing phase for the "Autonomous Plant Monitoring System," we will focus on verifying the functionality and interconnectivity of the system's components. This includes testing the accuracy of sensor signals, especially the humidity sensors, under various controlled conditions to ensure they display correct readings. We will also test the reliability of data transmission from the sensors to our website, ensuring that the sensor data is accurately and promptly updated on the web interface. Additionally, our testing will cover the system's ability to control the sensors remotely via the website, including the crucial aspect of the humidity sensors controlling the servo mechanism based on specific humidity levels, such as adjusting watering systems in response to the plant's needs. This comprehensive testing approach is designed to confirm the effectiveness and reliability of our autonomous plant monitoring system in real-world scenarios.


Result

In the culmination of our project, we successfully developed a comprehensive website for our "Autonomous Plant Monitoring System." This interactive platform allows users to select from a variety of plants, each with its unique moisture requirements. Based on these requirements, the system automatically controls a servo mechanism to water the plants as needed. Moreover, the website offers additional functionality, enabling users to manually control the watering schedule and light settings. This dual-mode operation—automatic based on plant-specific humidity levels and manual control via the website—ensures flexible and precise care for each plant. The successful implementation of this system represents a significant achievement in automating plant care, offering a user-friendly and efficient solution for plant enthusiasts and gardeners alike.


Generic placeholder image

Zhihao Xu

zx334@cornell.edu

Designed the system structure. Tested the whole system. Made parts of website, project report and demonstration video

Generic placeholder image

Yiqi Sun

ys2257@cornell.edu

Designed the system structure. Tested the whole system. Made parts of website, project report and demonstration video


Parts List

  • Raspberry Pi $35.00
  • Raspberry Pi Camera V2 $25.00
  • LEDs, Resistors and Wires, servo, humidity sensor, soli moisture sensor, water tank, - Provided in lab

Total: $60


References

PiCamera Document
Tower Pro Servo Datasheet
Bootstrap
parallax servo
Pigpio Library
R-Pi GPIO Document

Code Appendix


                from flask import Flask, render_template, jsonify, Response, request
                from picamera import PiCamera
                import RPi.GPIO as GPIO
                from time import sleep
                import io
                import adafruit_dht
                import board
                import time
                
                app = Flask(__name__)
                # Servo setup
                SERVO_PIN = 17
                LIGHT_PIN = 21
                GPIO.setmode(GPIO.BCM)
                GPIO.setup(SERVO_PIN, GPIO.OUT)
                GPIO.setup(LIGHT_PIN, GPIO.OUT)
                pwm = GPIO.PWM(SERVO_PIN, 50)
                pwm.start(0)
                
                current_angle = 0  # Global variable to track the servo angle
                light_status = False
                plant_humidity_thresholds = {
                    'tomato': 50,
                    'potato': 64,
                    'lettuce': 30
                }
                # Initialize the DHT11 sensor once
                dhtDevice = adafruit_dht.DHT11(board.D4, use_pulseio=False)
                def adjust_servo_based_on_humidity(humidity, threshold):
                    global current_angle
                    if humidity < threshold and current_angle != 90:
                        set_servo_angle(90)
                        current_angle = 90
                    elif humidity >= threshold and current_angle != 0:
                        set_servo_angle(0)
                        current_angle = 0
                
                def get_sensor_data():
                    for _ in range(3):  # Try up to 3 times
                        try:
                            temperature = dhtDevice.temperature
                            humidity = dhtDevice.humidity
                            if temperature is not None and humidity is not None:
                                return temperature, humidity
                        except RuntimeError as e:
                            print("Retrying sensor read:", e)
                            time.sleep(2.0)
                    return None, None  # Indicate failure after retries
                
                def toggle_light_status():
                    global light_status
                    light_status = not light_status
                    GPIO.output(LIGHT_PIN, light_status)
                
                
                def set_servo_angle(angle):
                    duty_cycle = angle / 18 + 2
                    pwm.ChangeDutyCycle(duty_cycle)
                    time.sleep(1)
                    pwm.ChangeDutyCycle(0)
                @app.route('/toggle-light', methods=['POST'])
                def toggle_light():
                    toggle_light_status()
                    return jsonify({"message": "Light toggled"})
                @app.route('/toggle-pump', methods=['POST'])
                def toggle_pump():
                    global current_angle
                    # Toggle between 0 and 90 degrees
                    if current_angle == 0:
                        new_angle = 90
                    else:
                        new_angle = 0
                
                    set_servo_angle(new_angle)
                    current_angle = new_angle
                    return jsonify({"new_angle": current_angle})
                
                def generate_video_stream():
                    with PiCamera() as camera:
                        camera.resolution = (640, 480)
                        camera.framerate = 24
                        stream = io.BytesIO()
                
                        for _ in camera.capture_continuous(stream, 'jpeg', use_video_port=True):
                            stream.seek(0)
                            frame = stream.read()
                            yield (b'--frame\r\n'
                                   b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
                            stream.seek(0)
                            stream.truncate()
                
                @app.route('/')
                def index():
                    return render_template('index.html')
                
                @app.route('/sensor-data')
                def sensor_data():
                    temperature, humidity = get_sensor_data()
                    if temperature is not None and humidity is not None:
                        selected_plant = request.args.get('plant', 'tomato')  # 默认为番茄
                        adjust_servo_based_on_humidity(humidity, plant_humidity_thresholds[selected_plant])
                        return jsonify({'temperature': temperature, 'humidity': humidity})
                    else:
                        return jsonify({'temperature': 'N/A', 'humidity': 'N/A'})
                @app.route('/video-stream')
                def video_stream():
                    return Response(generate_video_stream(),
                                    mimetype='multipart/x-mixed-replace; boundary=frame')
                
                if __name__ == '__main__':
                    app.run(host='0.0.0.0', port=5000, debug=True)